package org.esprit.ocm.client.ui.ec2;

import java.util.ArrayList;
import java.util.List;

import org.esprit.ocm.client.model.ec2.ImageRecord;
import org.esprit.ocm.client.model.ec2.datasource.GroupLocalDS;
import org.esprit.ocm.client.model.ec2.datasource.KeyPairLocalDS;
import org.esprit.ocm.client.rpc.ec2.ImageService;
import org.esprit.ocm.client.rpc.ec2.ImageServiceAsync;
import org.esprit.ocm.client.rpc.ec2.KeyPairService;
import org.esprit.ocm.client.rpc.ec2.KeyPairServiceAsync;
import org.esprit.ocm.client.rpc.ec2.SecurityGroupService;
import org.esprit.ocm.client.rpc.ec2.SecurityGroupServiceAsync;
import org.esprit.ocm.dto.ec2.impl.GroupDescriptionMappingDto;
import org.esprit.ocm.dto.ec2.impl.KeyPairInfoMappingDto;
import org.esprit.ocm.dto.impl.AwsCredentialsDto;
import org.esprit.ocm.dto.impl.ServerDto;
import org.esprit.ocm.dto.impl.UserDto;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.ButtonItem;
import com.smartgwt.client.widgets.form.fields.ComboBoxItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.SliderItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.fields.events.ClickEvent;
import com.smartgwt.client.widgets.form.fields.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;

public class RunInstance extends Window {

	private final ImageServiceAsync			imageService			= GWT.create(ImageService.class);
	private final KeyPairServiceAsync		keyPairService			= GWT.create(KeyPairService.class);
	private final SecurityGroupServiceAsync	securityGroupService	= GWT.create(SecurityGroupService.class);

	private SelectItem						keypairCB;
	private DataSource						dsKeypair;
	private ListGrid						grid;
	private DataSource						dsGrp;

	public RunInstance(final ImageRecord ir, final ServerDto server, final AwsCredentialsDto credentials, final UserDto user) {

		getData(server, credentials);

		setTitle("Run Instance");
		setWidth(400);
		setHeight(560);
		setIsModal(true);
		setShowModalMask(true);
		setShowCloseButton(true);
		centerInPage();

		final DynamicForm form1 = new DynamicForm();
		form1.setWidth(350);
		form1.setHeight(180);
		form1.setPadding(5);
		form1.setLayoutAlign(VerticalAlignment.TOP);

		final DynamicForm form2 = new DynamicForm();
		form2.setWidth(350);
		form2.setHeight(150);
		form2.setPadding(5);
		form2.setLayoutAlign(VerticalAlignment.TOP);

		final DynamicForm form3 = new DynamicForm();
		form3.setWidth(350);
		form3.setHeight(50);
		form3.setPadding(5);
		form3.setLayoutAlign(VerticalAlignment.TOP);

		VLayout vLayout = new VLayout();

		HLayout hLayout1 = new HLayout();
		hLayout1.setWidth("20%");
		HLayout hLayout2 = new HLayout();
		hLayout2.setWidth("30%");
		HLayout hLayout3 = new HLayout();
		hLayout3.setWidth("20%");

		vLayout.addMember(hLayout1);
		vLayout.addMember(hLayout2);
		vLayout.addMember(hLayout3);

		TextItem imageID = new TextItem("imageID");
		imageID.setTitle("Image ID");
		imageID.setRequired(true);
		imageID.setValue(ir.getId());
		imageID.setDisabled(true);

		TextItem kernel = new TextItem("kernelID");
		kernel.setTitle("Kernel ID");
		kernel.setRequired(true);
		kernel.setValue(ir.getKernelId());
		kernel.setDisabled(true);

		TextItem ramdisk = new TextItem("ramdiskID");
		ramdisk.setTitle("Ramdisk ID");
		ramdisk.setRequired(true);
		ramdisk.setValue(ir.getRamdiskId());
		ramdisk.setDisabled(true);

		Label groupLabel = new Label();
		groupLabel.setHeight(20);
		groupLabel.setLeft(30);
		groupLabel.setAlign(Alignment.LEFT);
		groupLabel.setContents("<b>Groups<b>");
		groupLabel.draw();

		/**
		 * 
		 * Possible values:
		 * <ul>
		 * <li>DEFAULT ("m1.small")</li>
		 * <li>LARGE ("m1.large")</li>
		 * <li>XLARGE ("m1.xlarge")</li>
		 * <li>MEDIUM_HCPU ("c1.medium")</li>
		 * <li>XLARGE_HCPU ("c1.xlarge")</li>
		 * <li>XLARGE_HMEM ("m2.xlarge")</li>
		 * <li>XLARGE_DOUBLE_HMEM ("m2.2xlarge")</li>
		 * <li>XLARGE_QUAD_HMEM ("m2.4xlarge")</li>
		 * <li>XLARGE_CLUSTER_COMPUTE ("cc1.4xlarge")</li>
		 * </ul>
		 */
		final ComboBoxItem typeCB = new ComboBoxItem();
		typeCB.setTitle("<b>Type<b>");
		typeCB.setType("comboBox");
		typeCB.setDefaultValue("m1.small");
		typeCB.setValueMap("m1.small", "m1.large", "m1.xlarge", "c1.medium", "c1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "cc1.4xlarge");

		keypairCB = new SelectItem();
		keypairCB.setTitle("<b>Keypair<b>");
		// keypairCB.setType("comboBox");
		// keypairCB.setValueMap();

		final ComboBoxItem zoneCB = new ComboBoxItem();
		zoneCB.setTitle("<b>Availability Zone<b>");
		zoneCB.setType("comboBox");
		zoneCB.setDefaultValue("<any>");
		zoneCB.setValueMap("<any>", "192.168.100.200");

		final SliderItem sliderItem = new SliderItem();
		sliderItem.setTitle("<b>Instance number<b>");
		sliderItem.setWidth(250);
		sliderItem.setMinValue(0);
		sliderItem.setMaxValue(10);
		sliderItem.setDefaultValue(1);

		// HStack hStack = new HStack(10);
		// hStack.setHeight(160);
		// hStack.setWidth(300);
		// hStack.setTop(20);
		//
		// grp1 = new PartsListGrid();
		// grp1.setTitle("Groups");
		// grp1.setCanDragRecordsOut(true);
		// grp1.setCanAcceptDroppedRecords(true);
		// grp1.setCanReorderFields(true);
		// grp1.setDragDataAction(DragDataAction.MOVE);
		// hStack.addMember(grp1);
		//
		// final PartsListGrid myList2 = new PartsListGrid();
		// myList2.setCanDragRecordsOut(true);
		// myList2.setCanAcceptDroppedRecords(true);
		// myList2.setCanReorderRecords(true);
		//
		// VStack vStack = new VStack(10);
		// vStack.setWidth(32);
		// vStack.setHeight(74);
		// vStack.setLayoutAlign(Alignment.CENTER);
		//
		// TransferImgButton rightImg = new
		// TransferImgButton(TransferImgButton.RIGHT);
		// rightImg.addClickHandler(new
		// com.smartgwt.client.widgets.events.ClickHandler() {
		//
		// public void onClick(com.smartgwt.client.widgets.events.ClickEvent
		// event) {
		// myList2.transferSelectedData(grp1);
		//
		// }
		// });
		//
		// vStack.addMember(rightImg);
		//
		// TransferImgButton leftImg = new
		// TransferImgButton(TransferImgButton.LEFT);
		// leftImg.addClickHandler(new
		// com.smartgwt.client.widgets.events.ClickHandler() {
		//
		// public void onClick(com.smartgwt.client.widgets.events.ClickEvent
		// event) {
		// grp1.transferSelectedData(myList2);
		//
		// }
		// });
		//
		// vStack.addMember(leftImg);
		//
		// hStack.addMember(vStack);
		// hStack.addMember(myList2);
		//
		// hStack.setPadding(5);
		// hStack.draw();

		grid = new ListGrid();
		grid.setTitle("<b>Groups</b>");
		grid.setWidth(250);
		grid.setHeight(200);
		grid.setSelectionType(SelectionStyle.MULTIPLE);
		grid.setCanDragSelect(true);
		grid.setShowFilterEditor(true);
		grid.setFilterOnKeypress(true);
		grid.setAutoFetchData(true);
		grid.setLeft(35);

		ButtonItem launchButton = new ButtonItem("launch", "Launch Instance");
		launchButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {

				String imageId = ir.getId();

				ListGridRecord[] groupsSelected = grid.getSelection();
				List<String> groups = new ArrayList<String>();
				for (ListGridRecord i : groupsSelected) {
					groups.add(i.getAttribute("name"));
				}

				String keyName = (String) keypairCB.getValue();
				byte[] userData = null;
				String instanceType = (String) typeCB.getValue();
				int count = (Integer) sliderItem.getValue();

				String availabilityZone;
				if (zoneCB.getValue().equals("<any>")) {

					availabilityZone = "";
				} else {
					availabilityZone = (String) zoneCB.getValue();
				}

				String kernelId = ir.getKernelId();
				String ramdiskId = ir.getRamdiskId();

				imageService.runInstance(imageId, groups, keyName, userData, instanceType, count, availabilityZone, kernelId, ramdiskId, server,
						credentials, new AsyncCallback<String>() {
							
							public void onSuccess(String s) {

								SC.warn(s);
							}
							
							public void onFailure(Throwable s) {
								SC.warn(s.getLocalizedMessage());
							}
						});

				destroy();
			}
		});

		form1.setFields(imageID, kernel, ramdisk, typeCB, keypairCB, zoneCB, sliderItem);
		form2.addChild(grid);
		form3.setFields(launchButton);
		form1.redraw();
		form2.redraw();
		form3.redraw();

		hLayout1.addChild(form1);
		hLayout2.addChild(form2);
		hLayout3.addChild(form3);
		addItem(vLayout);

		draw();
	}

	private void getData(ServerDto server, AwsCredentialsDto credentials) {

		securityGroupService.listSecurityGroups(server, credentials, new AsyncCallback<List<GroupDescriptionMappingDto>>() {

			public void onSuccess(List<GroupDescriptionMappingDto> list) {

				for (GroupDescriptionMappingDto g : list) {
					System.out.println("*-*" + g.getName());
				}
				dsGrp = GroupLocalDS.getInstance(list);
				grid.setDataSource(dsGrp);

				ListGridField name = new ListGridField("name", "name");
				grid.setFields(name);
			}

			public void onFailure(Throwable arg0) {
			}
		});

		keyPairService.listKeypairs(server, credentials, new AsyncCallback<List<KeyPairInfoMappingDto>>() {

			public void onSuccess(List<KeyPairInfoMappingDto> list) {

				for (KeyPairInfoMappingDto k : list) {
					System.out.println("*-*" + k.getKeyName());
				}
				// if (dsKeypair.isCreated()) {
				// dsKeypair.destroy();
				// }
				// else {
				//
				// dsKeypair = KeyPairLocalDS.getInstance(list);
				// }
				dsKeypair = KeyPairLocalDS.getInstance(list);

				ListGridField keyName = new ListGridField("keyName", "keyName");

				keypairCB.setOptionDataSource(dsKeypair);
				keypairCB.setDefaultToFirstOption(true);
				// keypairCB.setWidth(150);
				keypairCB.setValueField("keyName");
				keypairCB.setDisplayField("keyName");
				// keypairCB.setPickListWidth(450);
				keypairCB.setPickListFields(keyName);

			}

			public void onFailure(Throwable arg0) {
			}
		});
	}
}
